package com.xuecheng.content.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xuecheng.basic.api.BasicClient;
import com.xuecheng.commons.constants.CourseConstants;
import com.xuecheng.commons.enums.ErrorCode;
import com.xuecheng.commons.model.vo.CategoryVo;
import com.xuecheng.commons.model.vo.ResponseResult;
import com.xuecheng.commons.model.vo.TeachplanVo;
import com.xuecheng.commons.utils.BeanHelper;
import com.xuecheng.content.config.MinioProperties;
import com.xuecheng.content.domain.CourseBase;
import com.xuecheng.content.domain.CoursePub;
import com.xuecheng.content.mappers.CoursePubMapper;
import com.xuecheng.content.service.CourseBaseService;
import com.xuecheng.content.service.CoursePubService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuecheng.content.service.TeachplanService;
import com.xuecheng.web.exception.BusinessException;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * <p>
 * 课程发布 服务实现类
 * </p>
 *
 * @author itheima
 * @since 2022-07-17
 */
@Service
public class CoursePubServiceImpl extends ServiceImpl<CoursePubMapper, CoursePub> implements CoursePubService {

    @Autowired
    TeachplanService teachplanService;

    @Autowired
    CourseBaseService courseBaseService;

    @Autowired
    BasicClient basicClient;

    @Autowired
    PublishHtmlService publishHtmlService;

    @Autowired
    RabbitTemplate rabbitTemplate;
    /**
     * 获取预览的课程发布数据
     * 1.课程信息
     * 2.课程老师
     * 3.课程计划信息
     * 将3部分数据，转化成页面所需要的map集合
     * coursePub：课程发布对象数据
     * teachplanNode：课程计划数据
     */
    @Override
    public Map preview(Long courseBaseId) {
        //1.判断参数(略)
        //2.查询课程计划信息
        ResponseResult<TeachplanVo> treeNodesResult = teachplanService.treeNodes(courseBaseId);
        TeachplanVo teachplanVo = treeNodesResult.getData();
        //3.创建coursePub课程发布对象
        //3.1 向课程发布对象中设置课程信息
        //查询课程信息
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        //设置到coursePub中
        CoursePub coursePub = BeanHelper.copyProperties(courseBase, CoursePub.class);     //同类型，同属性名copy
        //设置课程id
        coursePub.setCourseId(courseBaseId);
        //设置课程价格
        coursePub.setPrice(courseBase.getPrice());
        //设置分类名称到coursePub
        coursePub.setMtName(getCategoryName(coursePub.getMt())) ;
        coursePub.setStName(getCategoryName(coursePub.getSt())) ;
        //3.2 向课程发布对象中设置课程计划信息
        coursePub.setTeachplan(JSON.toJSONString(teachplanVo));
        //3.3 向课程发布对象中设置老师信息(略)
        //4.构造返回
        Map map = new HashMap();
        map.put("teachplanNode",teachplanVo);  //课程计划
        map.put("coursePub",coursePub);  //发布
        return map;
    }

    //根据id,调用feign接口查询分类名称
    public String getCategoryName (String id) {
        ResponseResult<CategoryVo> result = basicClient.findById(id);
        CategoryVo categoryVo = result.getData();
        return categoryVo.getName();
    }

    /**
     * 课程发布
     * 1.保存课程发布数据到mysql中
     */
    @Override
    public ResponseResult publish(Long courseBaseId) throws Exception {
        //第一步：保存课程发布数据到数据库
        //1.参数判断(略)--courseBaseId是否为空，课程是否存在，课程是否审核通过
        CourseBase courseBase = courseBaseService.getById(courseBaseId);
        if (!CourseConstants.AUDIT_PASTED_STATUS.equals(courseBase.getAuditStatus())) {
            throw new BusinessException(ErrorCode.COURSEPUBSHRRROR);
        }
        //2.构造课程发布表数据
        Map preview = this.preview(courseBaseId);
        CoursePub coursePub = (CoursePub) preview.get("coursePub");
        coursePub.setId(null);  //为了避免id被误设置值
        //3.查询课程发布数据：根据课程id(course_id)查询某个课程是否已经发布
        LambdaQueryWrapper<CoursePub> qw = new LambdaQueryWrapper<>();
        qw.eq(CoursePub::getCourseId,courseBaseId);
        CoursePub one = this.getOne(qw);
        if (one == null) {
        //3.1 如果不存在，保存
            this.save(coursePub);
        } else {
        //3.2 如果存在，更新
            coursePub.setId(one.getId());
            this.updateById(coursePub);
        }
        //4 修改课程状态，将审核状态设置为已发布
        courseBase.setAuditStatus(CourseConstants.AUDIT_PUBLISHED_STATUS);
        courseBaseService.updateById(courseBase);
        //第二步:生成HTML页面，存入到minio中
        publishHtmlService.publish(preview,coursePub.getId());
        //第三步:发送mq消息
        rabbitTemplate.convertAndSend("content-exchange-one","course.pub",coursePub.getId()); //交换机，路由键，消息
        return ResponseResult.okResult();
    }
}
